home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / mozilla-firefox / include / xpcom / nsBaseHashtable.h < prev    next >
C/C++ Source or Header  |  2006-05-08  |  14KB  |  456 lines

  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is C++ hashtable templates.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Benjamin Smedberg.
  19.  * Portions created by the Initial Developer are Copyright (C) 2002
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38. #ifndef nsBaseHashtable_h__
  39. #define nsBaseHashtable_h__
  40.  
  41. #include "nsTHashtable.h"
  42. #include "prlock.h"
  43. #include "nsDebug.h"
  44.  
  45. template<class KeyClass,class DataType,class UserDataType>
  46. class nsBaseHashtable; // forward declaration
  47.  
  48. /**
  49.  * the private nsTHashtable::EntryType class used by nsBaseHashtable
  50.  * @see nsTHashtable for the specification of this class
  51.  * @see nsBaseHashtable for template parameters
  52.  */
  53. template<class KeyClass,class DataType>
  54. class nsBaseHashtableET : public KeyClass
  55. {
  56. public:
  57.   DataType mData;
  58.   friend class nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >;
  59.  
  60. private:
  61.   typedef typename KeyClass::KeyType KeyType;
  62.   typedef typename KeyClass::KeyTypePointer KeyTypePointer;
  63.   
  64.   nsBaseHashtableET(KeyTypePointer aKey);
  65.   nsBaseHashtableET(nsBaseHashtableET<KeyClass,DataType>& toCopy);
  66.   ~nsBaseHashtableET();
  67. };
  68.  
  69. /**
  70.  * templated hashtable for simple data types
  71.  * This class manages simple data types that do not need construction or
  72.  * destruction.
  73.  *
  74.  * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
  75.  *   for a complete specification.
  76.  * @param DataType the datatype stored in the hashtable,
  77.  *   for example, PRUint32 or nsCOMPtr.  If UserDataType is not the same,
  78.  *   DataType must implicitly cast to UserDataType
  79.  * @param UserDataType the user sees, for example PRUint32 or nsISupports*
  80.  */
  81. template<class KeyClass,class DataType,class UserDataType>
  82. class nsBaseHashtable :
  83.   protected nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >
  84. {
  85. public:
  86.   typedef typename KeyClass::KeyType KeyType;
  87.   typedef nsBaseHashtableET<KeyClass,DataType> EntryType;
  88.  
  89.   // default constructor+destructor are fine
  90.  
  91.   /**
  92.    * Initialize the object.
  93.    * @param initSize the initial number of buckets in the hashtable,
  94.    *        default 16
  95.    * locking on all class methods
  96.    * @return    PR_TRUE if the object was initialized properly.
  97.    */
  98.   PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE)
  99.   { return nsTHashtable<EntryType>::Init(initSize); }
  100.  
  101.   /**
  102.    * Check whether the table has been initialized.
  103.    * This function is especially useful for static hashtables.
  104.    * @return PR_TRUE if the table has been initialized.
  105.    */
  106.   PRBool IsInitialized() const { return this->mTable.entrySize; }
  107.  
  108.   /**
  109.    * Return the number of entries in the table.
  110.    * @return    number of entries
  111.    */
  112.   PRUint32 Count() const
  113.   { return nsTHashtable<EntryType>::Count(); }
  114.  
  115.   /**
  116.    * retrieve the value for a key.
  117.    * @param aKey the key to retreive
  118.    * @param pData data associated with this key will be placed at this
  119.    *   pointer.  If you only need to check if the key exists, pData
  120.    *   may be null.
  121.    * @return PR_TRUE if the key exists. If key does not exist, pData is not
  122.    *   modified.
  123.    */
  124.   PRBool Get(KeyType aKey, UserDataType* pData) const
  125.   {
  126.     EntryType* ent = GetEntry(aKey);
  127.  
  128.     if (!ent)
  129.       return PR_FALSE;
  130.  
  131.     if (pData)
  132.       *pData = ent->mData;
  133.  
  134.     return PR_TRUE;
  135.   }
  136.  
  137.   /**
  138.    * put a new value for the associated key
  139.    * @param aKey the key to put
  140.    * @param aData the new data
  141.    * @return always PR_TRUE, unless memory allocation failed
  142.    */
  143.   PRBool Put(KeyType aKey, UserDataType aData)
  144.   {
  145.     EntryType* ent = PutEntry(aKey);
  146.  
  147.     if (!ent)
  148.       return PR_FALSE;
  149.  
  150.     ent->mData = aData;
  151.  
  152.     return PR_TRUE;
  153.   }
  154.  
  155.   /**
  156.    * remove the data for the associated key
  157.    * @param aKey the key to remove from the hashtable
  158.    */
  159.   void Remove(KeyType aKey) { RemoveEntry(aKey); }
  160.  
  161.   /**
  162.    * function type provided by the application for enumeration.
  163.    * @param aKey the key being enumerated
  164.    * @param aData data being enumerated
  165.    * @parm userArg passed unchanged from Enumerate
  166.    * @return either
  167.    *   @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink or
  168.    *   @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
  169.    */
  170.   typedef PLDHashOperator
  171.     (*PR_CALLBACK EnumReadFunction)(KeyType      aKey,
  172.                                     UserDataType aData,
  173.                                     void*        userArg);
  174.  
  175.   /**
  176.    * enumerate entries in the hashtable, without allowing changes
  177.    * @param enumFunc enumeration callback
  178.    * @param userArg passed unchanged to the EnumReadFunction
  179.    */
  180.   PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const
  181.   {
  182.     NS_ASSERTION(this->mTable.entrySize,
  183.                  "nsBaseHashtable was not initialized properly.");
  184.  
  185.     s_EnumReadArgs enumData = { enumFunc, userArg };
  186.     return PL_DHashTableEnumerate(NS_CONST_CAST(PLDHashTable*, &this->mTable),
  187.                                   s_EnumReadStub,
  188.                                   &enumData);
  189.   }
  190.  
  191.   /**
  192.    * function type provided by the application for enumeration.
  193.    * @param aKey the key being enumerated
  194.    * @param aData Reference to data being enumerated, may be altered. e.g. for
  195.    *        nsInterfaceHashtable this is an nsCOMPtr reference...
  196.    * @parm userArg passed unchanged from Enumerate
  197.    * @return bitflag combination of
  198.    *   @link PLDHashOperator::PL_DHASH_REMOVE @endlink,
  199.    *   @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink, or
  200.    *   @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
  201.    */
  202.   typedef PLDHashOperator
  203.     (*PR_CALLBACK EnumFunction)(KeyType       aKey,
  204.                                 DataType&     aData,
  205.                                 void*         userArg);
  206.  
  207.   /**
  208.    * enumerate entries in the hashtable, allowing changes. This
  209.    * functions write-locks the hashtable.
  210.    * @param enumFunc enumeration callback
  211.    * @param userArg passed unchanged to the EnumFunction
  212.    */
  213.   PRUint32 Enumerate(EnumFunction enumFunc, void* userArg)
  214.   {
  215.     NS_ASSERTION(this->mTable.entrySize,
  216.                  "nsBaseHashtable was not initialized properly.");
  217.  
  218.     s_EnumArgs enumData = { enumFunc, userArg };
  219.     return PL_DHashTableEnumerate(&this->mTable,
  220.                                   s_EnumStub,
  221.                                   &enumData);
  222.   }
  223.  
  224.   /**
  225.    * reset the hashtable, removing all entries
  226.    */
  227.   void Clear() { nsTHashtable<EntryType>::Clear(); }
  228.  
  229. protected:
  230.   /**
  231.    * used internally during EnumerateRead.  Allocated on the stack.
  232.    * @param func the enumerator passed to EnumerateRead
  233.    * @param userArg the userArg passed to EnumerateRead
  234.    */
  235.   struct s_EnumReadArgs
  236.   {
  237.     EnumReadFunction func;
  238.     void* userArg;
  239.   };
  240.  
  241.   static PLDHashOperator s_EnumReadStub(PLDHashTable    *table,
  242.                                         PLDHashEntryHdr *hdr,
  243.                                         PRUint32         number,
  244.                                         void            *arg);
  245.  
  246.   struct s_EnumArgs
  247.   {
  248.     EnumFunction func;
  249.     void* userArg;
  250.   };
  251.  
  252.   static PLDHashOperator s_EnumStub(PLDHashTable      *table,
  253.                                     PLDHashEntryHdr   *hdr,
  254.                                     PRUint32           number,
  255.                                     void              *arg);
  256. };
  257.  
  258. /**
  259.  * This class is a thread-safe version of nsBaseHashtable.
  260.  */
  261. template<class KeyClass,class DataType,class UserDataType>
  262. class nsBaseHashtableMT :
  263.   protected nsBaseHashtable<KeyClass,DataType,UserDataType>
  264. {
  265. public:
  266.   typedef typename
  267.     nsBaseHashtable<KeyClass,DataType,UserDataType>::EntryType EntryType;
  268.   typedef typename
  269.     nsBaseHashtable<KeyClass,DataType,UserDataType>::KeyType KeyType;
  270.   typedef typename
  271.     nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumFunction EnumFunction;
  272.   typedef typename
  273.     nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumReadFunction EnumReadFunction;
  274.  
  275.   nsBaseHashtableMT() : mLock(nsnull) { }
  276.   ~nsBaseHashtableMT();
  277.  
  278.   PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE);
  279.   PRBool IsInitialized() const { return (PRBool) mLock; }
  280.   PRUint32 Count() const;
  281.   PRBool Get(KeyType aKey, UserDataType* pData) const;
  282.   PRBool Put(KeyType aKey, UserDataType aData);
  283.   void Remove(KeyType aKey);
  284.  
  285.   PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const;
  286.   PRUint32 Enumerate(EnumFunction enumFunc, void* userArg);
  287.   void Clear();
  288.  
  289. protected:
  290.   PRLock* mLock;
  291. };
  292.   
  293.  
  294. //
  295. // nsBaseHashtableET definitions
  296. //
  297.  
  298. template<class KeyClass,class DataType>
  299. nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET(KeyTypePointer aKey) :
  300.   KeyClass(aKey)
  301. { }
  302.  
  303. template<class KeyClass,class DataType>
  304. nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET
  305.   (nsBaseHashtableET<KeyClass,DataType>& toCopy) :
  306.   KeyClass(toCopy),
  307.   mData(toCopy.mData)
  308. { }
  309.  
  310. template<class KeyClass,class DataType>
  311. nsBaseHashtableET<KeyClass,DataType>::~nsBaseHashtableET()
  312. { }
  313.  
  314.  
  315. //
  316. // nsBaseHashtable definitions
  317. //
  318.  
  319. template<class KeyClass,class DataType,class UserDataType>
  320. PLDHashOperator
  321. nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumReadStub
  322.   (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg)
  323. {
  324.   EntryType* ent = NS_STATIC_CAST(EntryType*, hdr);
  325.   s_EnumReadArgs* eargs = (s_EnumReadArgs*) arg;
  326.  
  327.   PLDHashOperator res = (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
  328.  
  329.   NS_ASSERTION( !(res & PL_DHASH_REMOVE ),
  330.                 "PL_DHASH_REMOVE return during const enumeration; ignoring.");
  331.  
  332.   if (res & PL_DHASH_STOP)
  333.     return PL_DHASH_STOP;
  334.  
  335.   return PL_DHASH_NEXT;
  336. }
  337.  
  338. template<class KeyClass,class DataType,class UserDataType>
  339. PLDHashOperator
  340. nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumStub
  341.   (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg)
  342. {
  343.   EntryType* ent = NS_STATIC_CAST(EntryType*, hdr);
  344.   s_EnumArgs* eargs = (s_EnumArgs*) arg;
  345.  
  346.   return (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
  347. }
  348.  
  349.  
  350. //
  351. // nsBaseHashtableMT  definitions
  352. //
  353.  
  354. template<class KeyClass,class DataType,class UserDataType>
  355. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::~nsBaseHashtableMT()
  356. {
  357.   if (this->mLock)
  358.     PR_DestroyLock(this->mLock);
  359. }
  360.  
  361. template<class KeyClass,class DataType,class UserDataType>
  362. PRBool
  363. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Init(PRUint32 initSize)
  364. {
  365.   if (!nsTHashtable<EntryType>::IsInitialized() && !nsTHashtable<EntryType>::Init(initSize))
  366.     return PR_FALSE;
  367.  
  368.   this->mLock = PR_NewLock();
  369.   NS_WARN_IF_FALSE(this->mLock, "Error creating lock during nsBaseHashtableL::Init()");
  370.  
  371.   return (this->mLock != nsnull);
  372. }
  373.  
  374. template<class KeyClass,class DataType,class UserDataType>
  375. PRUint32
  376. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Count() const
  377. {
  378.   PR_Lock(this->mLock);
  379.   PRUint32 count = nsTHashtable<EntryType>::Count();
  380.   PR_Unlock(this->mLock);
  381.  
  382.   return count;
  383. }
  384.  
  385. template<class KeyClass,class DataType,class UserDataType>
  386. PRBool
  387. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Get(KeyType       aKey,
  388.                                                            UserDataType* pData) const
  389. {
  390.   PR_Lock(this->mLock);
  391.   PRBool res =
  392.     nsBaseHashtable<KeyClass,DataType,UserDataType>::Get(aKey, pData);
  393.   PR_Unlock(this->mLock);
  394.  
  395.   return res;
  396. }
  397.  
  398. template<class KeyClass,class DataType,class UserDataType>
  399. PRBool
  400. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Put(KeyType      aKey,
  401.                                                            UserDataType aData)
  402. {
  403.   PR_Lock(this->mLock);
  404.   PRBool res =
  405.     nsBaseHashtable<KeyClass,DataType,UserDataType>::Put(aKey, aData);
  406.   PR_Unlock(this->mLock);
  407.  
  408.   return res;
  409. }
  410.  
  411. template<class KeyClass,class DataType,class UserDataType>
  412. void
  413. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Remove(KeyType aKey)
  414. {
  415.   PR_Lock(this->mLock);
  416.   nsBaseHashtable<KeyClass,DataType,UserDataType>::Remove(aKey);
  417.   PR_Unlock(this->mLock);
  418. }
  419.  
  420. template<class KeyClass,class DataType,class UserDataType>
  421. PRUint32
  422. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::EnumerateRead
  423.   (EnumReadFunction fEnumCall, void* userArg) const
  424. {
  425.   PR_Lock(this->mLock);
  426.   PRUint32 count =
  427.     nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead(fEnumCall, userArg);
  428.   PR_Unlock(this->mLock);
  429.  
  430.   return count;
  431. }
  432.  
  433. template<class KeyClass,class DataType,class UserDataType>
  434. PRUint32
  435. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Enumerate
  436.   (EnumFunction fEnumCall, void* userArg)
  437. {
  438.   PR_Lock(this->mLock);
  439.   PRUint32 count =
  440.     nsBaseHashtable<KeyClass,DataType,UserDataType>::Enumerate(fEnumCall, userArg);
  441.   PR_Unlock(this->mLock);
  442.  
  443.   return count;
  444. }
  445.  
  446. template<class KeyClass,class DataType,class UserDataType>
  447. void
  448. nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Clear()
  449. {
  450.   PR_Lock(this->mLock);
  451.   nsBaseHashtable<KeyClass,DataType,UserDataType>::Clear();
  452.   PR_Unlock(this->mLock);
  453. }
  454.  
  455. #endif // nsBaseHashtable_h__
  456.